using MediatR;
using Microsoft.EntityFrameworkCore;
using RBAC.Domain.SmartHealthcare;
using RBAC.Domain.SmartHealthcare.Hosiptial;
using RBAC.ErrorCode;
using RBAC.Interstructrue;
using RBAC.Interstructrue.Base;
using SmartHealthcare.Read.Api.Application.Command.PatientList;
using SmartHealthcare.Read.Api.DTo;

namespace SmartHealthcare.Read.Api.Application.Handler.PatientList
{
    /// <summary>
    /// 获取患者信息处理器
    /// </summary>
    public class GetPatientInfoHandler : IRequestHandler<GetPatientInfoCommand, APIResult<List<PatientInfoDto>>>
    {
        private readonly RBACDbContext _dbContext;
        private readonly ILogger<GetPatientInfoHandler> _logger;

        public GetPatientInfoHandler(RBACDbContext dbContext, ILogger<GetPatientInfoHandler> logger)
        {
            _dbContext = dbContext;
            _logger = logger;
        }

        /// <summary>
        /// 获取患者信息
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task<APIResult<List<PatientInfoDto>>> Handle(GetPatientInfoCommand request, CancellationToken cancellationToken)
        {
            var result = new APIResult<List<PatientInfoDto>>();

            try
            {
                // 检查是否有查询参数
                if (!request.HasAnyParameter())
                {
                    _logger.LogInformation("未提供查询参数，将查询所有患者信息");
                }
                else
                {
                    _logger.LogInformation($"开始查询患者信息，病人卡号：{request.MedicalCard}，病房号：{request.HospitalRoomCode}");
                }

                // 构建查询
                var query = from registry in _dbContext.inpatientRegistries
                           join patient in _dbContext.patientLists on registry.MedicalCard equals patient.MedicalCard
                           join department in _dbContext.Departments on registry.DepartmentId equals department.Id
                           join room in _dbContext.hospitalRooms on registry.WardNo equals room.Id
                           join bed in _dbContext.HospitalBeds on registry.WardId equals bed.Id
                           where registry.IsDeleted == false
                             && patient.IsDeleted == false
                             && department.IsDeleted == false
                             && room.IsDeleted == false
                             && bed.IsDeleted == false
                           select new
                           {
                               registry.MedicalCard,
                               registry.DepartmentId,
                               registry.WardNo,
                               registry.WardId,
                               registry.AdmissionTime,
                               registry.AdvancePayment,
                               registry.Discharge_status,
                               patient.Name,
                               department.DepartmentName,
                               room.HospitalRoomCode,
                               bed.HospitalBedId
                           };

                // 根据参数筛选
                if (!string.IsNullOrWhiteSpace(request.MedicalCard))
                {
                    query = query.Where(x => x.MedicalCard == request.MedicalCard);
                }

                if (request.HospitalRoomCode.HasValue)
                {
                    query = query.Where(x => x.HospitalRoomCode == request.HospitalRoomCode.Value);
                }

                var patientInfos = await query.ToListAsync(cancellationToken);

                var resultList = new List<PatientInfoDto>();

                foreach (var info in patientInfos)
                {
                    // 计算已用金额（从费用明细表统计）
                    var usedAmount = await _dbContext.expenseDetails
                        .Where(x => x.MedicalCard == info.MedicalCard && x.IsDeleted == false)
                        .SumAsync(x => x.TotalAmount, cancellationToken);

                    // 计算余额
                    var balance = info.AdvancePayment - usedAmount;

                    var patientInfoDto = new PatientInfoDto
                    {
                        MedicalCard = info.MedicalCard,
                        PatientName = info.Name,
                        DepartmentId = info.DepartmentId,
                        DepartmentName = info.DepartmentName,
                        HospitalRoomCode = info.HospitalRoomCode,
                        HospitalBedId = info.HospitalBedId,
                        AdmissionTime = info.AdmissionTime,
                        AdvancePayment = info.AdvancePayment,
                        UsedAmount = usedAmount,
                        Balance = balance,
                        DischargeStatus = info.Discharge_status
                    };

                    resultList.Add(patientInfoDto);
                }

                result.Data = resultList;
                result.Code = APIEnums.Success;
                result.Msg = $"查询成功，共找到{resultList.Count}条记录";

                _logger.LogInformation($"查询患者信息成功，共找到{resultList.Count}条记录");
            }
            catch (Exception ex)
            {
                result.Code = APIEnums.Fail;
                result.Msg = "查询患者信息失败";
                _logger.LogError(ex, "查询患者信息时发生异常");
            }

            return result;
        }
    }
} 